| Current Path : /home/ataenra/www/administrator/components/com_sppagebuilder/editor/traits/ |
| Current File : /home/ataenra/www/administrator/components/com_sppagebuilder/editor/traits/AiContentUploadTrait.php |
<?php
/**
* @package SP Page Builder
* @author JoomShaper http://www.joomshaper.com
* @copyright Copyright (c) 2010 - 2023 JoomShaper
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or later
*/
use Joomla\CMS\Factory;
use Joomla\CMS\Uri\Uri;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Filesystem\Path;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Filesystem\Folder;
use Joomla\CMS\Layout\FileLayout;
use Joomla\CMS\Helper\MediaHelper;
use Joomla\CMS\Component\ComponentHelper;
// No direct access
defined('_JEXEC') or die('Restricted access');
JLoader::register('SppagebuilderHelperImage', JPATH_ROOT . '/components/com_sppagebuilder/helpers/image.php');
/**
* Media trait files for managing the CRUD operation.
*
* @version 4.1.0
*/
trait AiContentUploadTrait
{
/**
* OpenAi endpoint for the API.
*
* @return void
* @version 4.1.0
*/
public function aiContentUpload()
{
$method = $this->getInputMethod();
$this->checkNotAllowedMethods(['GET', 'PATCH', 'PUT', 'DELETE'], $method);
switch ($method)
{
case 'POST':
$this->uploadAiGeneratedImageFromUrl();
break;
}
}
/**
* Upload image from url
*
* @return void
* @version 4.1.0
*/
private function uploadAiGeneratedImageFromUrl()
{
$model = $this->getModel('Media');
$user = Factory::getUser();
$imageUrl = $this->getInput('url', '', 'STRING');
$aspectRatio = $this->getInput('aspect_ratio', '', 'STRING');
$canCreate = $user->authorise('core.create', 'com_sppagebuilder');
$report = [];
if (!$canCreate)
{
$report['status'] = false;
$report['message'] = Text::_('JERROR_ALERTNOAUTHOR');
$this->sendResponse($report, 403);
}
// Validate the URL
if (!filter_var($imageUrl, FILTER_VALIDATE_URL)) {
$report['status'] = false;
$report['message'] = Text::_('Invalid url');
$this->sendResponse($report, 400);
}
// Generate a unique filename
$extension = 'webp';
$base_name = uniqid('ai_img_', true);
$filename = $base_name . '.' . $extension;
// Save the image to the server
$mediaParams = ComponentHelper::getParams('com_media');
$folder_root = $mediaParams->get('file_path', 'images') . '/';
$date = Factory::getDate();
$folder = $folder_root . HTMLHelper::_('date', $date, 'Y') . '/' . HTMLHelper::_('date', $date, 'm') . '/' . HTMLHelper::_('date', $date, 'd');
if (!Folder::exists(JPATH_ROOT . '/' . $folder))
{
Folder::create(JPATH_ROOT . '/' . $folder, 0755);
}
if (!Folder::exists(JPATH_ROOT . '/' . $folder . '/_spmedia_thumbs'))
{
Folder::create(JPATH_ROOT . '/' . $folder . '/_spmedia_thumbs', 0755);
}
$src = Path::clean($folder . '/' . $filename);
$dest = Path::clean(JPATH_ROOT . '/' . $src);
$isImageSaved = !empty($aspectRatio) ? $this->changeAspectRatio($aspectRatio, $imageUrl, $dest) : $this->convertImageToWebp($imageUrl, $dest);
if(!$isImageSaved)
{
$report['status'] = false;
$report['message'] = Text::_('COM_SPPAGEBUILDER_MEDIA_MANAGER_UPLOAD_FAILED');
$this->sendResponse($report, 400);
}
$media_attr = [];
$thumb = '';
$image = new SppagebuilderHelperImage($dest);
$media_attr['full'] = ['height' => $image->height, 'width' => $image->width];
if (($image->width > 300) || ($image->height > 225))
{
$thumbDestPath = dirname($dest) . '/_spmedia_thumbs';
$created = $image->createThumb(array('300', '300'), $thumbDestPath, $base_name, $extension);
if ($created == false)
{
$report['status'] = false;
$report['message'] = Text::_('COM_SPPAGEBUILDER_MEDIA_MANAGER_FILE_NOT_SUPPORTED');
}
$report['src'] = Uri::root(true) . '/' . $folder . '/_spmedia_thumbs/' . $base_name . '.' . $extension;
$thumb = $folder . '/_spmedia_thumbs/' . $base_name . '.' . $extension;
$thumb_dest = Path::clean($thumbDestPath . '/' . $base_name . '.' . $extension);
list($width, $height) = getimagesize($thumb_dest);
$media_attr['thumbnail'] = ['height' => $height, 'width' => $width];
$report['thumb'] = $thumb;
}
else
{
$report['src'] = Uri::root(true) . '/' . $src;
$report['thumb'] = $src;
}
// Create placeholder for lazy load
$this->createAiGeneratedMediaPlaceholder($dest, $base_name, $extension);
$insert_id = $model->insertMedia($base_name, $src, json_encode($media_attr), $thumb, 'image');
$report['media_attr'] = $media_attr;
$report['status'] = true;
$report['title'] = $base_name;
$report['id'] = $insert_id;
$report['path'] = $src;
$layout_path = JPATH_ROOT . '/administrator/components/com_sppagebuilder/layouts';
$format_layout = new FileLayout('media.format', $layout_path);
$report['message'] = $format_layout->render(array('media' => $model->getMediaByID($insert_id), 'innerHTML' => true));
$this->sendResponse($report, 200);
}
private static function is_in_array($needle, $haystack)
{
$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($haystack));
foreach ($it as $element)
{
if ($element == $needle)
{
return true;
}
}
return false;
}
/**
* @since 2020
* Create light weight image placeholder for lazy load feature
*/
private function createAiGeneratedMediaPlaceholder($dest, $base_name, $ext)
{
$placeholder_folder_path = JPATH_ROOT . '/media/com_sppagebuilder/placeholder';
if (!Folder::exists($placeholder_folder_path))
{
Folder::create($placeholder_folder_path, 0755);
}
$image = new SppagebuilderHelperImage($dest);
list($srcWidth, $srcHeight) = $image->getDimension();
$width = 60;
$height = $width / ($srcWidth / $srcHeight);
$image->createThumb(array('60', $height), $placeholder_folder_path, $base_name, $ext, 20);
}
private function getImageSource($image_path)
{
$image_properties = @getimagesize($image_path);
$image_type = $image_properties[2];
$imageSource = false;
switch ($image_type)
{
case 1:
$imageSource = @imagecreatefromgif($image_path);
break;
case 2:
$imageSource = @imagecreatefromjpeg($image_path);
break;
case 3:
$imageSource = @imagecreatefrompng($image_path);
break;
}
return $imageSource;
}
private function convertImageToWebp($image_path, $destination)
{
$image = $this->getImageSource($image_path);
if(!$image)
{
return false;
}
// get dimensions of image
$width = imagesx($image);
$height = imagesy($image);
// create a canvas
$canvas = imagecreatetruecolor ($width, $height);
imageAlphaBlending($canvas, false);
imageSaveAlpha($canvas, true);
// By default, the canvas is black, so make it transparent
$transparent = imagecolorallocatealpha($canvas, 0, 0, 0, 127);
imagefilledrectangle($canvas, 0, 0, $width - 1, $height - 1, $transparent);
// copy image to canvas
imagecopy($canvas, $image, 0, 0, 0, 0, $width, $height);
// save canvas as a webp
$is_image_saved = imagewebp($canvas, $destination, 80); // 80 is the quality parameter (0-100)
// clean up memory
imagedestroy($canvas);
return $is_image_saved;
}
private function changeAspectRatio($aspect_ratio, $image_path, $destination)
{
$sourceImage = $this->getImageSource($image_path);
if(!$sourceImage)
{
return false;
}
// Calculate the new dimensions while maintaining the aspect ratio
$sourceWidth = imagesx($sourceImage);
$sourceHeight = imagesy($sourceImage);
$parts = explode(':', $aspect_ratio);
$aspectRatio = $parts[0] / $parts[1];
// Calculate the target width and height based on the aspect ratio
if ($sourceWidth / $sourceHeight > $aspectRatio) {
$newWidth = round($sourceHeight * $aspectRatio);
$newHeight = $sourceHeight;
} else {
$newWidth = $sourceWidth;
$newHeight = round($sourceWidth / $aspectRatio);
}
// Create a new image with the desired dimensions
$newImage = @imagecreatetruecolor($newWidth, $newHeight);
if(!$newImage)
{
return false;
}
// Resize the source image to fit the new dimensions
$isSuccess = @imagecopyresampled($newImage, $sourceImage, 0, 0, 0, 0, $newWidth, $newHeight, $sourceWidth, $sourceHeight);
if(!$isSuccess){
return false;
}
// save canvas as a webp
$isSuccess = @imagewebp($newImage, $destination, 80); // 80 is the quality parameter (0-100)
// Clean up resources
imagedestroy($sourceImage);
imagedestroy($newImage);
return $isSuccess;
}
}