/** * Create an image with a possible filters. * * @param AssetFileModel $asset * @param array $params */ public function image($asset, $params = array()) { // We require an AssetFileModel if (!$asset instanceof AssetFileModel && !isset($asset->filename, $asset->folderId)) { return false; } // Is it a proper image file? if (!in_array(strtolower(IOHelper::getExtension($asset->filename)), $this->_allowedExtensions)) { return false; } // Update image params and validate them $imageParams = array_merge($this->_defaultParams, $params); if (!isset($imageParams['width']) || !isset($imageParams['height'])) { return false; } if (!is_array($imageParams['filters']) || !is_numeric(key($imageParams['filters']))) { $imageParams['filters'] = array($imageParams['filters']); } // Do we know the source folder path? if (!isset($this->_imageFolders[$asset->folderId])) { $assetFolder = craft()->assets->getFolderById($asset->folderId); $assetSource = $assetFolder->getSource(); $assetSettings = $assetSource->settings; if ($assetFolder->path) { $assetSettings['url'] = $assetSettings['url'] . $assetFolder->path; $assetSettings['path'] = $assetSettings['path'] . $assetFolder->path; } $this->_imageFolders[$asset->folderId] = $assetSettings; } $this->_asset = $asset; $this->_url = craft()->config->parseEnvironmentString($this->_imageFolders[$asset->folderId]['url']); $this->_path = craft()->config->parseEnvironmentString($this->_imageFolders[$asset->folderId]['path']); // Transform! return $this->_createImageTransform($imageParams); }
/** * @return mixed */ public function getExtension() { if (!$this->_extension) { $this->_extension = IOHelper::getExtension($this->getRealPath()); } return $this->_extension; }
/** * Includes resources for the Control Panel from the craft/config/diywidget/ folder. */ protected function includeCustomCpResources() { $templatePaths = []; $folderPath = craft()->path->getConfigPath() . 'diywidget/'; if (IOHelper::folderExists($folderPath)) { $filePaths = glob($folderPath . '*.{twig,html,css,js}', GLOB_BRACE); foreach ($filePaths as $filePath) { $pathInFolder = str_replace($folderPath, '', $filePath); $resourcePath = 'config/diywidget/' . $pathInFolder; switch (IOHelper::getExtension($filePath)) { case 'twig': case 'html': $templatePaths[] = $pathInFolder; break; case 'css': craft()->templates->includeCssResource($resourcePath); break; case 'js': craft()->templates->includeJsResource($resourcePath); break; } } } craft()->diyWidget->templatePaths = $templatePaths; }
/** * Renders a template, and either outputs or returns it. * * @param mixed $template The name of the template to load in a format supported by * {@link TemplatesService::findTemplate()}, or a {@link StringTemplate} object. * @param array $variables The variables that should be available to the template. * @param bool $return Whether to return the results, rather than output them. (Default is `false`.) * @param bool $processOutput Whether the output should be processed by {@link processOutput()}. * * @throws HttpException * @return mixed The rendered template if $return is set to `true`. */ public function renderTemplate($template, $variables = array(), $return = false, $processOutput = false) { if (($output = craft()->templates->render($template, $variables)) !== false) { if ($processOutput) { $output = $this->processOutput($output); } if ($return) { return $output; } else { // Set the MIME type for the request based on the matched template's file extension (unless the // Content-Type header was already set, perhaps by the template via the {% header %} tag) if (!HeaderHelper::isHeaderSet('Content-Type')) { // Safe to assume that findTemplate() will return an actual template path here, and not `false`. // If the template didn't exist, a TemplateLoaderException would have been thrown when calling // craft()->templates->render(). $templateFile = craft()->templates->findTemplate($template); $extension = IOHelper::getExtension($templateFile, 'html'); if ($extension == 'twig') { $extension = 'html'; } HeaderHelper::setContentTypeByExtension($extension); } // Set the charset header HeaderHelper::setHeader(array('charset' => 'utf-8')); // Are we serving HTML or XHTML? if (in_array(HeaderHelper::getMimeType(), array('text/html', 'application/xhtml+xml'))) { // Are there any head/foot nodes left in the queue? $headHtml = craft()->templates->getHeadHtml(); $footHtml = craft()->templates->getFootHtml(); if ($headHtml) { if (($endHeadPos = mb_stripos($output, '</head>')) !== false) { $output = mb_substr($output, 0, $endHeadPos) . $headHtml . mb_substr($output, $endHeadPos); } else { $output .= $headHtml; } } if ($footHtml) { if (($endBodyPos = mb_stripos($output, '</body>')) !== false) { $output = mb_substr($output, 0, $endBodyPos) . $footHtml . mb_substr($output, $endBodyPos); } else { $output .= $footHtml; } } } // Output it into a buffer, in case TasksService wants to close the connection prematurely ob_start(); echo $output; // End the request craft()->end(); } } else { throw new HttpException(404); } }
/** * Constructor * * @param null $imagePath * @param null $imageUrl */ public function __construct($imagePath = null, $imageUrl = null) { if ($imagePath != 'null') { $this['path'] = $imagePath; $imageInfo = @getimagesize($imagePath); $this['width'] = $imageInfo[0]; $this['height'] = $imageInfo[1]; $this['extension'] = IOHelper::getExtension($imagePath); $this['mimeType'] = IOHelper::getMimeType($imagePath); $this['size'] = IOHelper::getFileSize($imagePath); } if ($imageUrl != 'null') { $this['url'] = $imageUrl; } }
public function init() { craft()->on('assets.onSaveAsset', function (Event $event) { $asset = $event->params['asset']; if (craft()->imageResizer->getSettings()->enabled) { // Only process if it's a new asset being saved. if ($event->params['isNewAsset']) { // Is this a manipulatable image? if (ImageHelper::isImageManipulatable(IOHelper::getExtension($asset->filename))) { craft()->imageResizer->resize($asset); } } } }); }
/** * Upload a logo for the admin panel. * * @return null */ public function actionUploadSiteImage() { $this->requireAjaxRequest(); $this->requireAdmin(); $type = craft()->request->getRequiredPost('type'); if (!in_array($type, $this->_allowedTypes)) { $this->returnErrorJson(Craft::t('That is not an accepted site image type.')); } // Upload the file and drop it in the temporary folder $file = UploadedFile::getInstanceByName('image-upload'); try { // Make sure a file was uploaded if ($file) { $fileName = AssetsHelper::cleanAssetName($file->getName()); if (!ImageHelper::isImageManipulatable($file->getExtensionName())) { throw new Exception(Craft::t('The uploaded file is not an image.')); } $folderPath = craft()->path->getTempUploadsPath(); IOHelper::ensureFolderExists($folderPath); IOHelper::clearFolder($folderPath, true); move_uploaded_file($file->getTempName(), $folderPath . $fileName); // Test if we will be able to perform image actions on this image if (!craft()->images->checkMemoryForImage($folderPath . $fileName)) { IOHelper::deleteFile($folderPath . $fileName); $this->returnErrorJson(Craft::t('The uploaded image is too large')); } list($width, $height) = ImageHelper::getImageSize($folderPath . $fileName); if (IOHelper::getExtension($fileName) != 'svg') { craft()->images->cleanImage($folderPath . $fileName); } else { craft()->images->loadImage($folderPath . $fileName)->saveAs($folderPath . $fileName); } $constraint = 500; // If the file is in the format badscript.php.gif perhaps. if ($width && $height) { // Never scale up the images, so make the scaling factor always <= 1 $factor = min($constraint / $width, $constraint / $height, 1); $html = craft()->templates->render('_components/tools/cropper_modal', array('imageUrl' => UrlHelper::getResourceUrl('tempuploads/' . $fileName), 'width' => round($width * $factor), 'height' => round($height * $factor), 'factor' => $factor, 'constraint' => $constraint, 'fileName' => $fileName)); $this->returnJson(array('html' => $html)); } } } catch (Exception $exception) { $this->returnErrorJson($exception->getMessage()); } $this->returnErrorJson(Craft::t('There was an error uploading your photo')); }
/** * Renders a template, and either outputs or returns it. * * @param mixed $template The name of the template to load, or a StringTemplate object. * @param array $variables The variables that should be available to the template * @param bool $return Whether to return the results, rather than output them * @param bool $processOutput * @throws HttpException * @return mixed */ public function renderTemplate($template, $variables = array(), $return = false, $processOutput = false) { if (($output = craft()->templates->render($template, $variables)) !== false) { if ($processOutput) { $output = $this->processOutput($output); } if ($return) { return $output; } else { // Get the template file's MIME type $templateFile = craft()->templates->findTemplate($template); $extension = IOHelper::getExtension($templateFile, 'html'); $mimeType = IOHelper::getMimeTypeByExtension('.' . $extension); if (!$mimeType) { $mimeType = 'text/html'; } header('Content-Type: ' . $mimeType . '; charset=utf-8'); if ($mimeType == 'text/html') { // Are there any head/foot nodes left in the queue? $headHtml = craft()->templates->getHeadHtml(); $footHtml = craft()->templates->getFootHtml(); if ($headHtml) { if (($endHeadPos = stripos($output, '</head>')) !== false) { $output = substr($output, 0, $endHeadPos) . $headHtml . substr($output, $endHeadPos); } else { $output .= $headHtml; } } if ($footHtml) { if (($endBodyPos = stripos($output, '</body>')) !== false) { $output = substr($output, 0, $endBodyPos) . $footHtml . substr($output, $endBodyPos); } else { $output .= $footHtml; } } } // Output to the browser! echo $output; // End the request craft()->end(); } } else { throw new HttpException(404); } }
public function getTemplateFiles() { $folderEmpty = true; if (IOHelper::isFolderEmpty(craft()->path->getPluginsPath() . 'formbuilder2/templates/email/layouts')) { throw new HttpException(404, Craft::t('Looks like you don\'t have any templates in your email/layouts folder.')); } else { $folderEmpty = false; } $fileList = IOHelper::getFolderContents(craft()->path->getPluginsPath() . 'formbuilder2/templates/email/layouts'); $files = []; $filesModel = []; if (!$folderEmpty) { foreach ($fileList as $key => $file) { $files[$key] = ['fileName' => IOHelper::getFileName($file, false), 'fileOriginalName' => IOHelper::getFileName($file), 'fileNameCleaned' => IOHelper::cleanFilename(IOHelper::getFileName($file, false)), 'fileExtension' => IOHelper::getExtension($file), 'filePath' => $file, 'fileContents' => IOHelper::getFileContents($file)]; $filesModel[] = FormBuilder2_FileModel::populateModel($files[$key]); } } return $filesModel; }
/** * Clean an Asset's filename. * * @param $name * @param bool $isFilename if set to true (default), will separate extension * and clean the filename separately. * * @return mixed */ public static function cleanAssetName($name, $isFilename = true) { if ($isFilename) { $baseName = IOHelper::getFileName($name, false); $extension = '.' . IOHelper::getExtension($name); } else { $baseName = $name; $extension = ''; } $separator = craft()->config->get('filenameWordSeparator'); if (!is_string($separator)) { $separator = null; } $baseName = IOHelper::cleanFilename($baseName, craft()->config->get('convertFilenamesToAscii'), $separator); if ($isFilename && empty($baseName)) { $baseName = '-'; } return $baseName . $extension; }
/** * Upload a logo for the admin panel. * * @return null */ public function actionUploadLogo() { $this->requireAjaxRequest(); $this->requireAdmin(); // Upload the file and drop it in the temporary folder $file = $_FILES['image-upload']; try { // Make sure a file was uploaded if (!empty($file['name']) && !empty($file['size'])) { $folderPath = craft()->path->getTempUploadsPath(); IOHelper::ensureFolderExists($folderPath); IOHelper::clearFolder($folderPath, true); $fileName = AssetsHelper::cleanAssetName($file['name']); move_uploaded_file($file['tmp_name'], $folderPath . $fileName); // Test if we will be able to perform image actions on this image if (!craft()->images->checkMemoryForImage($folderPath . $fileName)) { IOHelper::deleteFile($folderPath . $fileName); $this->returnErrorJson(Craft::t('The uploaded image is too large')); } list($width, $height) = ImageHelper::getImageSize($folderPath . $fileName); if (IOHelper::getExtension($fileName) != 'svg') { craft()->images->cleanImage($folderPath . $fileName); } else { // Resave svg files as png $newFilename = preg_replace('/\\.svg$/i', '.png', $fileName); craft()->images->loadImage($folderPath . $fileName, $width, $height)->saveAs($folderPath . $newFilename); IOHelper::deleteFile($folderPath . $fileName); $fileName = $newFilename; } $constraint = 500; // If the file is in the format badscript.php.gif perhaps. if ($width && $height) { // Never scale up the images, so make the scaling factor always <= 1 $factor = min($constraint / $width, $constraint / $height, 1); $html = craft()->templates->render('_components/tools/cropper_modal', array('imageUrl' => UrlHelper::getResourceUrl('tempuploads/' . $fileName), 'width' => round($width * $factor), 'height' => round($height * $factor), 'factor' => $factor, 'constraint' => $constraint, 'fileName' => $fileName)); $this->returnJson(array('html' => $html)); } } } catch (Exception $exception) { $this->returnErrorJson($exception->getMessage()); } $this->returnErrorJson(Craft::t('There was an error uploading your photo')); }
/** * Loads an image from a file system path. * * @param string $path * @return Image * @throws Exception */ public function loadImage($path) { if (!IOHelper::fileExists($path)) { throw new Exception(Craft::t('No file exists at the path “{path}”', array('path' => $path))); } if (!craft()->images->setMemoryForImage($path)) { throw new Exception(Craft::t("Not enough memory available to perform this image operation.")); } $imageInfo = @getimagesize($path); if (!is_array($imageInfo)) { throw new Exception(Craft::t('The file “{path}” does not appear to be an image.', array('path' => $path))); } $this->_image = $this->_instance->open($path); $this->_extension = IOHelper::getExtension($path); $this->_imageSourcePath = $path; $this->_width = $this->_image->getSize()->getWidth(); $this->_height = $this->_image->getSize()->getHeight(); return $this; }
public function getImageQuality($filename, $quality = null) { $desiredQuality = !$quality ? craft()->imageResizer->getSettings()->imageQuality : $quality; if (IOHelper::getExtension($filename) == 'png') { // Valid PNG quality settings are 0-9, so normalize and flip, because we're talking about compression // levels, not quality, like jpg and gif. $quality = round($desiredQuality * 9 / 100); $quality = 9 - $quality; if ($quality < 0) { $quality = 0; } if ($quality > 9) { $quality = 9; } } else { $quality = $desiredQuality; } return $quality; }
/** * @param $srcZip * @param $destFolder * * @return bool */ public static function unzip($srcZip, $destFolder) { craft()->config->maxPowerCaptain(); if (IOHelper::fileExists($srcZip)) { if (IOHelper::getExtension($srcZip) == 'zip') { if (!IOHelper::folderExists($destFolder)) { if (!IOHelper::createFolder($destFolder)) { Craft::log('Tried to create the unzip destination folder, but could not: ' . $destFolder, LogLevel::Error); return false; } } else { // If the destination folder exists and it has contents, clear them. if (($conents = IOHelper::getFolderContents($destFolder)) !== false) { // Begin the great purge. if (!IOHelper::clearFolder($destFolder)) { Craft::log('Tried to clear the contents of the unzip destination folder, but could not: ' . $destFolder, LogLevel::Error); return false; } } } $zip = static::_getZipInstance($srcZip); $result = $zip->unzip($srcZip, $destFolder); if ($result === true) { return $result; } else { Craft::log('There was an error unzipping the file: ' . $srcZip, LogLevel::Error); return false; } } else { Craft::log($srcZip . ' is not a zip file and cannot be unzipped.', LogLevel::Error); return false; } } else { Craft::log('Unzipping is only available for files.', LogLevel::Error); return false; } }
/** * Constructor * * @param null $imagePath * @param null $imageUrl */ public function __construct($imagePath = null, $imageUrl = null, $paths = null, $transform = null) { if ($imagePath != 'null') { $this['path'] = $imagePath; $this['extension'] = IOHelper::getExtension($imagePath); $this['mimeType'] = IOHelper::getMimeType($imagePath); $this['size'] = IOHelper::getFileSize($imagePath); $imageInfo = @getimagesize($imagePath); if (is_array($imageInfo) && $imageInfo[0] !== '' && $imageInfo[1] !== '') { $this['width'] = $imageInfo[0]; $this['height'] = $imageInfo[1]; } else { // Couldn't get size. Calculate size based on source image and transform. $sourceImageInfo = @getimagesize($paths->sourcePath . $paths->sourceFilename); $sourceSize = new \Imagine\Image\Box($sourceImageInfo[0], $sourceImageInfo[1]); $targetCrop = craft()->imager->getCropSize($sourceSize, $transform); $this['width'] = $targetCrop->getWidth(); $this['height'] = $targetCrop->getHeight(); } } if ($imageUrl != 'null') { $this['url'] = $imageUrl; } }
/** * Open file and parse translate tags. * * @param string $path * @param string $file * @param ElementCriteriaModel $criteria * * @return array */ protected function _parseFile($path, $file, ElementCriteriaModel $criteria) { // Collect matches in file $occurences = array(); // Get file contents $contents = IOHelper::getFileContents($file); // Get extension $extension = IOHelper::getExtension($file); // Get matches per extension foreach ($this->_expressions[$extension] as $regex) { // Match translation functions if (preg_match_all($regex, $contents, $matches)) { // Collect foreach ($matches[2] as $original) { // Translate $translation = Craft::t($original, array(), null, $criteria->locale); // Show translation in textfield $field = craft()->templates->render('_includes/forms/text', array('id' => ElementHelper::createSlug($original), 'name' => 'translation[' . $original . ']', 'value' => $translation, 'placeholder' => $translation)); // Fill element with translation data $element = TranslateModel::populateModel(array('id' => ElementHelper::createSlug($original), 'original' => $original, 'translation' => $translation, 'source' => $path, 'file' => $file, 'locale' => $criteria->locale, 'field' => $field)); // If searching, only return matches if ($criteria->search && !stristr($element->original, $criteria->search) && !stristr($element->translation, $criteria->search)) { continue; } // If wanting one status, ditch the rest if ($criteria->status && $criteria->status != $element->getStatus()) { continue; } // Collect in array $occurences[$original] = $element; } } } // Return occurences return $occurences; }
/** * Returns the size of an image based on its file path. * * @param string $filePath The path to the image * * @return array [$width, $height] */ public static function getImageSize($filePath) { if (IOHelper::getExtension($filePath) == 'svg') { $svg = IOHelper::getFileContents($filePath); return static::parseSvgSize($svg); } else { $image = craft()->images->loadImage($filePath); return array($image->getWidth(), $image->getHeight()); } }
/** * Return the thumbnail extension for a file. * * @param AssetFileModel $file * * @return string */ private function _getThumbExtension(AssetFileModel $file) { // For non-web-safe formats we go with jpg. if (!in_array(mb_strtolower(IOHelper::getExtension($file->filename)), ImageHelper::getWebSafeFormats())) { if ($file->getExtension() == 'svg' && craft()->images->isImagick()) { return 'png'; } return 'jpg'; } else { return $file->getExtension(); } }
/** * Validates that temp file is actually an image file * * @param string $remoteImagePath url of remote image * @param string $tempLocalImage file pointer to temp image * * @return boolean */ private function _validateImage($remoteImagePath, $tempLocalImage) { // Check to make sure the asset is an image if (IOHelper::getFileKind(IOHelper::getExtension($tempLocalImage)) === 'image' && substr(IOHelper::getMimeType($tempLocalImage), 0, 5) === 'image') { return true; } return false; }
/** * Merge a conflicting uploaded file. * * @param string $conflictResolution User response to conflict. * @param int $theNewFileId The id of the new file that is conflicting. * @param string $fileName The filename that is in the conflict. * * @return AssetOperationResponseModel */ private function _mergeUploadedFiles($conflictResolution, $theNewFileId, $fileName) { $theNewFile = $this->getFileById($theNewFileId); $folder = $theNewFile->getFolder(); $source = craft()->assetSources->getSourceTypeById($folder->sourceId); $fileId = null; switch ($conflictResolution) { case AssetConflictResolution::Replace: // Replace the actual file $targetFile = $this->findFile(array('folderId' => $folder->id, 'filename' => $fileName)); // If the file doesn't exist in the index, but just in the source, // quick-index it, so we have a File Model to work with. if (!$targetFile) { $targetFile = new AssetFileModel(); $targetFile->sourceId = $folder->sourceId; $targetFile->folderId = $folder->id; $targetFile->filename = $fileName; $targetFile->kind = IOHelper::getFileKind(IOHelper::getExtension($fileName)); $this->storeFile($targetFile); } $source->replaceFile($targetFile, $theNewFile); $fileId = $targetFile->id; // Falling through to delete the file // Falling through to delete the file case AssetConflictResolution::Cancel: $this->deleteFiles($theNewFileId); break; default: $fileId = $theNewFileId; break; } $response = new AssetOperationResponseModel(); $response->setSuccess(); if ($fileId) { $response->setDataItem('fileId', $fileId); } return $response; }
/** * @inheritDoc IFieldType::validate() * * @param array $value * * @return true|string|array */ public function validate($value) { $errors = parent::validate($value); if (!is_array($errors)) { $errors = array(); } $settings = $this->getSettings(); // Check if this field restricts files and if files are passed at all. if (isset($settings->restrictFiles) && !empty($settings->restrictFiles) && !empty($settings->allowedKinds) && is_array($value) && !empty($value)) { $allowedExtensions = static::_getAllowedExtensions($settings->allowedKinds); foreach ($value as $fileId) { $file = craft()->assets->getFileById($fileId); if ($file && !in_array(mb_strtolower(IOHelper::getExtension($file->filename)), $allowedExtensions)) { $errors[] = Craft::t('"{filename}" is not allowed in this field.', array('filename' => $file->filename)); } } } foreach ($this->_failedFiles as $file) { $errors[] = Craft::t('"{filename}" is not allowed in this field.', array('filename' => $file)); } if ($errors) { return $errors; } else { return true; } }
/** * Delete a file. * * @param AssetFileModel $file * @return AssetOperationResponseModel */ public function deleteFile(AssetFileModel $file) { // Delete all the created images, such as transforms, thumbnails $this->deleteCreatedImages($file); craft()->assetTransforms->deleteTransformRecordsByFileId($file->id); if (IOHelper::fileExists(craft()->path->getAssetsImageSourcePath() . $file->id . '.' . IOHelper::getExtension($file->filename))) { IOHelper::deleteFile(craft()->path->getAssetsImageSourcePath() . $file->id . '.' . IOHelper::getExtension($file->filename)); } // Delete DB record and the file itself. craft()->elements->deleteElementById($file->id); $this->_deleteSourceFile($file->getFolder(), $file->filename); $response = new AssetOperationResponseModel(); return $response->setSuccess(); }
/** * Saves the image to the target path. * * @param string $targetPath * @param boolean $autoQuality * * @throws \Imagine\Exception\RuntimeException * @return null */ public function saveAs($targetPath, $autoQuality = false) { if (IOHelper::getExtension($targetPath) == 'svg') { IOHelper::writeToFile($targetPath, $this->_svgContent); } else { throw new Exception(Craft::t("Manipulated SVG image rasterizing is unreliable. Please see ImagesService::loadImage()")); } return true; }
/** * Creates a new support ticket for the GetHelp widget. * * @return null */ public function actionSendSupportRequest() { $this->requirePostRequest(); craft()->config->maxPowerCaptain(); $success = false; $errors = array(); $zipFile = null; $tempFolder = null; $widgetId = craft()->request->getPost('widgetId'); $namespace = craft()->request->getPost('namespace'); $namespace = $namespace ? $namespace . '.' : ''; $getHelpModel = new GetHelpModel(); $getHelpModel->fromEmail = craft()->request->getPost($namespace . 'fromEmail'); $getHelpModel->message = trim(craft()->request->getPost($namespace . 'message')); $getHelpModel->attachLogs = (bool) craft()->request->getPost($namespace . 'attachLogs'); $getHelpModel->attachDbBackup = (bool) craft()->request->getPost($namespace . 'attachDbBackup'); $getHelpModel->attachTemplates = (bool) craft()->request->getPost($namespace . 'attachTemplates'); $getHelpModel->attachment = UploadedFile::getInstanceByName($namespace . 'attachAdditionalFile'); if ($getHelpModel->validate()) { $user = craft()->userSession->getUser(); // Add some extra info about this install $message = $getHelpModel->message . "\n\n" . "------------------------------\n\n" . 'Craft ' . craft()->getEditionName() . ' ' . craft()->getVersion() . '.' . craft()->getBuild(); $plugins = craft()->plugins->getPlugins(); if ($plugins) { $pluginNames = array(); foreach ($plugins as $plugin) { $pluginNames[] = $plugin->getName() . ' ' . $plugin->getVersion() . ' (' . $plugin->getDeveloper() . ')'; } $message .= "\nPlugins: " . implode(', ', $pluginNames); } $requestParamDefaults = array('sFirstName' => $user->getFriendlyName(), 'sLastName' => $user->lastName ? $user->lastName : 'Doe', 'sEmail' => $getHelpModel->fromEmail, 'tNote' => $message); $requestParams = $requestParamDefaults; $hsParams = array('helpSpotApiURL' => 'https://support.pixelandtonic.com/api/index.php'); try { if ($getHelpModel->attachLogs || $getHelpModel->attachDbBackup) { if (!$zipFile) { $zipFile = $this->_createZip(); } if ($getHelpModel->attachLogs && IOHelper::folderExists(craft()->path->getLogPath())) { // Grab it all. $logFolderContents = IOHelper::getFolderContents(craft()->path->getLogPath()); foreach ($logFolderContents as $file) { // Make sure it's a file. if (IOHelper::fileExists($file)) { Zip::add($zipFile, $file, craft()->path->getStoragePath()); } } } if ($getHelpModel->attachDbBackup && IOHelper::folderExists(craft()->path->getDbBackupPath())) { // Make a fresh database backup of the current schema/data. We want all data from all tables // for debugging. craft()->db->backup(); $backups = IOHelper::getLastModifiedFiles(craft()->path->getDbBackupPath(), 3); foreach ($backups as $backup) { if (IOHelper::getExtension($backup) == 'sql') { Zip::add($zipFile, $backup, craft()->path->getStoragePath()); } } } } if ($getHelpModel->attachment) { // If we don't have a zip file yet, create one now. if (!$zipFile) { $zipFile = $this->_createZip(); } $tempFolder = craft()->path->getTempPath() . StringHelper::UUID() . '/'; if (!IOHelper::folderExists($tempFolder)) { IOHelper::createFolder($tempFolder); } $tempFile = $tempFolder . $getHelpModel->attachment->getName(); $getHelpModel->attachment->saveAs($tempFile); // Make sure it actually saved. if (IOHelper::fileExists($tempFile)) { Zip::add($zipFile, $tempFile, $tempFolder); } } if ($getHelpModel->attachTemplates) { // If we don't have a zip file yet, create one now. if (!$zipFile) { $zipFile = $this->_createZip(); } if (IOHelper::folderExists(craft()->path->getLogPath())) { // Grab it all. $templateFolderContents = IOHelper::getFolderContents(craft()->path->getSiteTemplatesPath()); foreach ($templateFolderContents as $file) { // Make sure it's a file. if (IOHelper::fileExists($file)) { $templateFolderName = IOHelper::getFolderName(craft()->path->getSiteTemplatesPath(), false); $siteTemplatePath = craft()->path->getSiteTemplatesPath(); $tempPath = substr($siteTemplatePath, 0, strlen($siteTemplatePath) - strlen($templateFolderName) - 1); Zip::add($zipFile, $file, $tempPath); } } } } if ($zipFile) { $requestParams['File1_sFilename'] = 'SupportAttachment-' . IOHelper::cleanFilename(craft()->getSiteName()) . '.zip'; $requestParams['File1_sFileMimeType'] = 'application/zip'; $requestParams['File1_bFileBody'] = base64_encode(IOHelper::getFileContents($zipFile)); // Bump the default timeout because of the attachment. $hsParams['callTimeout'] = 120; } // Grab the license.key file. if (IOHelper::fileExists(craft()->path->getLicenseKeyPath())) { $requestParams['File2_sFilename'] = 'license.key'; $requestParams['File2_sFileMimeType'] = 'text/plain'; $requestParams['File2_bFileBody'] = base64_encode(IOHelper::getFileContents(craft()->path->getLicenseKeyPath())); } } catch (\Exception $e) { Craft::log('Tried to attach debug logs to a support request and something went horribly wrong: ' . $e->getMessage(), LogLevel::Warning); // There was a problem zipping, so reset the params and just send the email without the attachment. $requestParams = $requestParamDefaults; } require_once craft()->path->getLibPath() . 'HelpSpotAPI.php'; $hsapi = new \HelpSpotAPI($hsParams); $result = $hsapi->requestCreate($requestParams); if ($result) { if ($zipFile) { if (IOHelper::fileExists($zipFile)) { IOHelper::deleteFile($zipFile); } } if ($tempFolder) { IOHelper::clearFolder($tempFolder); IOHelper::deleteFolder($tempFolder); } $success = true; } else { $hsErrors = array_filter(preg_split("/(\r\n|\n|\r)/", $hsapi->errors)); $errors = array('Support' => $hsErrors); } } else { $errors = $getHelpModel->getErrors(); } $this->renderTemplate('_components/widgets/GetHelp/response', array('success' => $success, 'errors' => JsonHelper::encode($errors), 'widgetId' => $widgetId)); }
/** * Submit Entry * */ public function actionSubmitEntry() { $this->requirePostRequest(); // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // VARIABLES // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ $files = ''; $ajax = false; $passedValidation = true; $validationErrors = []; $submissionErrorMessage = []; $customSuccessMessage = ''; $customErrorMessage = ''; // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // FORM // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ $form = craft()->formBuilder2_entry->getFormByHandle(craft()->request->getPost('formHandle')); // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // FORM SUBMISSION // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ $formFields = $form->fieldLayout->getFieldLayout()->getFields(); // Get all form fields $submission = craft()->request->getPost(); // Get all values from the submitted form $submissionData = $this->filterSubmissionKeys($submission); // Fillter out unused submission data // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // FORM ATTRIBUTES // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ $attributes = $form->getAttributes(); $formSettings = $attributes['formSettings']; $spamProtectionSettings = $attributes['spamProtectionSettings']; $messageSettings = $attributes['messageSettings']; $notificationSettings = $attributes['notificationSettings']; // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // FORM SETTINGS ||| (1) Custom Redirect, (2) File Uploads, (3) Ajax Submissions // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // (1) Custom Redirect if ($formSettings['formRedirect']['customRedirect'] != '') { $redirectUrl = $formSettings['formRedirect']['customRedirectUrl']; } // (2) File Uploads if ($formSettings['hasFileUploads'] == '1') { foreach ($formFields as $key => $value) { $field = $value->getField(); switch ($field->type) { case 'Assets': foreach ($_FILES as $key => $value) { if (!$value['tmp_name'] == '') { $fileModel = new AssetFileModel(); $folderId = $field->settings['singleUploadLocationSource'][0]; $sourceId = $field->settings['singleUploadLocationSource'][0]; $fileModel->originalName = $value['tmp_name']; $fileModel->sourceId = $sourceId; $fileModel->folderId = $folderId; $fileModel->filename = IOHelper::getFileName($value['name']); $fileModel->kind = IOHelper::getFileKind(IOHelper::getExtension($value['name'])); $fileModel->size = filesize($value['tmp_name']); if ($value['tmp_name']) { $fileModel->dateModified = IOHelper::getLastTimeModified($value['tmp_name']); } if ($fileModel->kind == 'image') { list($width, $height) = ImageHelper::getImageSize($value['tmp_name']); $fileModel->width = $width; $fileModel->height = $height; } $files[$key] = $fileModel; } } break; } } } // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // FORM CUSTOM MESSAGES ||| (1) Success Message (2) Error Message // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // (1) Success Message $customSuccessMessage = $messageSettings['successMessage'] ? $messageSettings['successMessage'] : Craft::t('Submission was successful.'); // (2) Error Message $customErrorMessage = $messageSettings['errorMessage'] ? $messageSettings['errorMessage'] : Craft::t('There was a problem with your submission.'); // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // (3) Ajax Submissions if ($formSettings['ajaxSubmit'] == '1') { $this->requireAjaxRequest(); $ajax = true; } // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // FORM SPAM PROTECTION ||| (1) Timed Method (2) Honeypot Method // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // (1) Timed Method if ($spamProtectionSettings['spamTimeMethod'] == '1') { $formSubmissionTime = (int) craft()->request->getPost('spamTimeMethod'); $submissionDuration = time() - $formSubmissionTime; $allowedTime = (int) $spamProtectionSettings['spamTimeMethodTime']; if ($submissionDuration < $allowedTime) { if ($ajax) { $this->returnJson(['validationErrors' => [Craft::t('You submitted too fast, you are robot!')], 'customErrorMessage' => $customErrorMessage]); } else { $spamTimedMethod = false; $submissionErrorMessage[] = Craft::t('You submitted too fast, you are robot!'); } } else { $spamTimedMethod = true; } } else { $spamTimedMethod = true; } // (2) Honeypot Method if ($spamProtectionSettings['spamHoneypotMethod'] == '1') { $honeypotField = craft()->request->getPost('email-address-new'); if ($honeypotField != '') { if ($ajax) { $this->returnJson(['validationErrors' => [Craft::t('You tried the honey, you are robot bear!')], 'customErrorMessage' => $customErrorMessage]); } else { $spamHoneypotMethod = false; $submissionErrorMessage[] = Craft::t('You tried the honey, you are robot bear!'); } } else { $spamHoneypotMethod = true; } } else { $spamHoneypotMethod = true; } // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // NEW FORM MODEL // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ $submissionEntry = new FormBuilder2_EntryModel(); $submissionEntry->formId = $form->id; $submissionEntry->title = $form->name; $submissionEntry->files = $files; $submissionEntry->submission = $submissionData; // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // FAILED SUBMISSION REDIRECT W/MESSAGES (Spam Protection) // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ if ($submissionErrorMessage) { craft()->userSession->setFlash('error', $customErrorMessage); craft()->urlManager->setRouteVariables(array('errors' => $submissionErrorMessage)); } // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // VALIDATE SUBMISSION DATA // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ $validation = craft()->formBuilder2_entry->validateEntry($form, $submissionData); // if ($validation != '') { if (!empty($validation)) { if ($ajax) { $this->returnJson(['passedValidation' => false, 'validationErrors' => $validation, 'customErrorMessage' => $customErrorMessage]); } else { craft()->userSession->setFlash('error', $customErrorMessage); $passedValidation = false; return craft()->urlManager->setRouteVariables(['value' => $submissionData, 'errors' => $validation]); } } // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // PROCESS SUBMISSION ENTRY // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ if (!$submissionErrorMessage && $passedValidation && $spamTimedMethod && $spamHoneypotMethod) { $submissionResponseId = craft()->formBuilder2_entry->processSubmissionEntry($submissionEntry); if ($submissionResponseId) { // Notify Admin of Submission if ($notificationSettings['notifySubmission'] == '1') { $this->notifyAdminOfSubmission($submissionResponseId, $form); } // Successful Submission Messages if ($ajax) { $this->returnJson(['success' => true, 'customSuccessMessage' => $customSuccessMessage]); } else { craft()->userSession->setFlash('success', $customSuccessMessage); if ($formSettings['formRedirect']['customRedirect'] != '') { $this->redirect($redirectUrl); } else { $this->redirectToPostedUrl(); } } } else { // Submission Error Messages if ($ajax) { $this->returnJson(['error' => true, 'customErrorMessage' => $customErrorMessage]); } else { craft()->userSession->setFlash('error', $customErrorMessage); return craft()->urlManager->setRouteVariables(['value' => $submissionData, 'errors' => $validation]); } } } // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ }
/** * Get the file extension. * * @return mixed */ public function getExtension() { return IOHelper::getExtension($this->filename); }
/** * Delete all the generated images for this file. * * @param AssetFileModel $file The assetFileModel representing the file to delete any generated thumbnails for. * * @return null */ protected function deleteGeneratedThumbnails(AssetFileModel $file) { $thumbFolders = IOHelper::getFolderContents(craft()->path->getAssetsThumbsPath()); foreach ($thumbFolders as $folder) { if (is_dir($folder)) { IOHelper::deleteFile($folder . '/' . $file->id . '.' . IOHelper::getExtension($file->filename)); } } }
/** * Upload a file. * * @param array $file * @param int $folderId * * @return bool|int */ private function _uploadFile($file, $folderId) { $fileName = AssetsHelper::cleanAssetName($file['name']); // Save the file to a temp location and pass this on to the source type implementation $filePath = AssetsHelper::getTempFilePath(IOHelper::getExtension($fileName)); move_uploaded_file($file['tmp_name'], $filePath); $response = craft()->assets->insertFileByLocalPath($filePath, $fileName, $folderId); // Make sure the file is removed. IOHelper::deleteFile($filePath, true); // Prevent sensitive information leak. Just in case. $response->deleteDataItem('filePath'); // Return file ID return $response->getDataItem('fileId'); }
/** * @inheritDoc BaseAssetSourceType::insertFileInFolder() * * @param AssetFolderModel $folder * @param $filePath * @param $fileName * * @throws Exception * @return AssetFileModel */ protected function insertFileInFolder(AssetFolderModel $folder, $filePath, $fileName) { $fileName = AssetsHelper::cleanAssetName($fileName); $extension = IOHelper::getExtension($fileName); if (!IOHelper::isExtensionAllowed($extension)) { throw new Exception(Craft::t('This file type is not allowed')); } $uriPath = $this->_getPathPrefix() . $folder->path . $fileName; $this->_prepareForRequests(); $settings = $this->getSettings(); $fileInfo = $this->_s3->getObjectInfo($settings->bucket, $uriPath); if ($fileInfo) { $response = new AssetOperationResponseModel(); return $response->setPrompt($this->getUserPromptOptions($fileName))->setDataItem('fileName', $fileName); } clearstatcache(); $this->_prepareForRequests(); if (!$this->putObject($filePath, $this->getSettings()->bucket, $uriPath, \S3::ACL_PUBLIC_READ)) { throw new Exception(Craft::t('Could not copy file to target destination')); } $response = new AssetOperationResponseModel(); return $response->setSuccess()->setDataItem('filePath', $uriPath); }
/** * Saves the image to the target path. * * @param string $targetPath * @param bool $sanitizeAndAutoQuality * * @throws \Imagine\Exception\RuntimeException * @return null */ public function saveAs($targetPath, $sanitizeAndAutoQuality = false) { $extension = IOHelper::getExtension($targetPath); $options = $this->_getSaveOptions(false, $extension); $targetPath = IOHelper::getFolderName($targetPath).IOHelper::getFileName($targetPath, false).'.'.$extension; if (($extension == 'jpeg' || $extension == 'jpg' || $extension == 'png') && $sanitizeAndAutoQuality) { clearstatcache(); $originalSize = IOHelper::getFileSize($this->_imageSourcePath); $this->_autoGuessImageQuality($targetPath, $originalSize, $extension, 0, 200); } else { $this->_image->save($targetPath, $options); } return true; }