We sacrifice by not doing any other technology, so that you get the best of Magento.

We sacrifice by not doing any other technology, so that you get the best of Magento.

    Magento 2 Commands not working after upgrade to latest version

    After Upgrade Magento 2 latest version, sometimes CLI commands stopped working:

    – When you Run upgrade : php bin/magento setup:upgrade command The commands do nothing and show no error nor proceedings but just new line as Following Screenshot:

    Actual Result:

    Expected Result:
    The above command should run the commands to upgrade the database but it just shows a new line without proceeding.

    Please follow the below steps to resolve this issue  :

    Step 1: Add Zend framework in Root composer.json

    “autoload”: {
    
    “psr-4”: {
    
    “Magento\Framework\”: “lib/internal/Magento/Framework/”,
    
    “Magento\Setup\”: “setup/src/Magento/Setup/”,
    
    “Magento\”: “app/code/Magento/”,
    
    “Zend\Mvc\Controller\”: “setup/src/Zend/Mvc/Controller/”
    
    },

    Step 2: Run below Command

    “composer dumpautoload”.

    Taaddaa!!  Now the command should work properly.

    Upload and delete image though ajax in Magento 2

    As per my requirements, I have made a code to upload an image and given the various effects to the image.

    So please follow the below steps to achieve the functionality.

    Step1: Add below code in your .phtml file where you want to upload an image.

    <div class="container wallpapercustompage">
      <div class="row">
        <div class="col-lg-8">
          <div class="mainImage">
            <img src="<?php echo $this->getUrl(); ?>10221276943_45e198c6c6_4k.jpg" id="mainImageSrc" />
          </div>
          <div class="actions-save" style="display:none;">
              <button type="button" class="action-cancel" data-role="cancel-button" data-image="10221276943_45e198c6c6_4k.jpg" data-type="jpg" title="<?php echo __('Cancel'); ?>"><span><?php echo __('Cancel'); ?></span></button>
              <button type="button" class="action-apply" data-role="apply-button" data-image="10221276943_45e198c6c6_4k.jpg" data-type="jpg" title="<?php echo __('Apply'); ?>"><span><?php echo __('Apply'); ?></span></button>
          </div>
          <div class="actions">
              <button type="button" class="action-flip" data-role="flip-button" data-image="10221276943_45e198c6c6_4k.jpg" data-type="jpg" title="<?php echo __('Flip image'); ?>"><span><?php echo __('Flip image'); ?></span></button>
              <button type="button" class="action-bw" data-role="bw-button" data-image="10221276943_45e198c6c6_4k.jpg" data-type="jpg" title="<?php echo __('Black & White Filter'); ?>"><span><?php echo __('Black & White Filter'); ?></span></button>
              <button type="button" class="action-sepia" data-role="sepia-button" data-image="10221276943_45e198c6c6_4k.jpg" data-type="jpg" title="<?php echo __('Sepia Filter'); ?>"><span><?php echo __('Sepia Filter'); ?></span></button>
          </div>
        </div>
        <div class="col-lg-4">
          <form class="form-horizontal"  id="frm_attachment" name="frm_attachment" method="post" enctype="multipart/form-data" action="<?php echo $this->getUrl(); ?>wallpaper/index/customize">
              <div class="browse-wrap">
                <input accept="image/*" id="attachment" name="attachment" type="file" value="">
              </div>
              
              <div class="row">
                <button type="submit" id="uploadAttachment" class="btn btn-primary"><?php echo __('Submit'); ?></button>
              </div>
          </form>
    
          <div id="attachmentFiles"></div>
        </div>  
    	</div>
    </div>
    
    <style type="text/css">
        .mainImage-image-grayscale{ -webkit-filter: grayscale(100%); -moz-filter: grayscale(100%); -o-filter: grayscale(100%); -ms-filter: grayscale(100%); filter: grayscale(100%); }
    
        .mainImage-image-sepia{ -webkit-filter: sepia(100%); -moz-filter: sepia(100%); -o-filter: sepia(100%); -ms-filter: sepia(100%); filter: sepia(100%); }
    
        .mainImage-image-flip{ transform: scale(-1, 1); -moz-transform: scale(-1, 1); -webkit-transform: scale(-1, 1); -o-transform: scale(-1, 1); -khtml-transform: scale(-1, 1); -ms-transform: scale(-1, 1); }
    </style>
    
    
    <script>
    
    function getSizeInCM (sizeInPX) {  
       return sizeInPX * 2.54 / (96 * window.devicePixelRatio)
    };
    
    require(['jquery'], function ($) {
    
        $(document).ready(function ($) {
    
        	/**** Delete Image & Image Effects ****/
            $(document).on('click', '#attachmentFiles .action-remove', function(){
               if (window.confirm("Are you sure you want to delete?")) {
                   var attachmentPath = $(this).attr("data-image");
                   var divID = $(this).parents(".base-image").attr("id");
                   var imageID = $(this).parents(".base-image").find(".hiddneattachID").val();
                   
                   jQuery.ajax({
                        url: "<?php echo $this->getUrl(); ?>wallpaper/index/deleteCustomize?isAjax=true",
                        type: "POST",
                        data: {filename: attachmentPath, form_key: window.FORM_KEY, imageID:imageID},
                        showLoader: true,
                        success: function (response) {
                            if(response.success == true){
                                var parentElements = $(".base-image#"+divID).prev().children();
                                $(".base-image#"+divID).remove();
                                if($(".base-image").length > 0)
                                {
                                  $('#mainImageSrc').attr("src",parentElements.find('.wallpaper-image').attr('src'));
                                  parentElements.find('.selectImage').attr('checked','checked');
                                  var srcFilename = parentElements.find('.selectImage').attr('data-srcfilename');
                                  var srcType = parentElements.find('.selectImage').attr('data-srctype');
                                  $('.action-bw').attr('data-image',srcFilename).attr('data-type',srcType);
                                  $('.action-sepia').attr('data-image',srcFilename).attr('data-type',srcType);
                                  $('.action-flip').attr('data-image',srcFilename).attr('data-type',srcType);
                                  $('.action-cancel').attr('data-image',srcFilename).attr('data-type',srcType);
                                  $('.action-apply').attr('data-image',srcFilename).attr('data-type',srcType);
                                }
                                else
                                {
                                  $('#mainImageSrc').attr("src", "<?php echo $this->getUrl(); ?>10221276943_45e198c6c6_4k.jpg");
                                  var srcFilename = '10221276943_45e198c6c6_4k.jpg';
                                  var srcType = 'jpg';
                                  $('.action-bw').attr('data-image',srcFilename).attr('data-type',srcType);
                                  $('.action-sepia').attr('data-image',srcFilename).attr('data-type',srcType);
                                  $('.action-flip').attr('data-image',srcFilename).attr('data-type',srcType);
                                  $('.action-cancel').attr('data-image',srcFilename).attr('data-type',srcType);
                                  $('.action-apply').attr('data-image',srcFilename).attr('data-type',srcType);
                                }
                            }
                        },
                       error: function (response) {
                            alert(response.message);
                       }
                    });
               } 
            });
    
            $(document).on('click', '.action-bw', function(){
               var attachmentPath = $(this).attr("data-image");
               $('.mainImage').addClass('mainImage-image-grayscale');
               $('div.actions').hide();
               $('div.actions-save').show();
               $('.action-apply').attr('data-action', '1');
            });
    
            $(document).on('click', '.action-sepia', function(){
               var attachmentPath = $(this).attr("data-image");
               $('.mainImage').addClass('mainImage-image-sepia');
               $('div.actions').hide();
               $('div.actions-save').show();
               $('.action-apply').attr('data-action', '2');
            });
    
            $(document).on('click', '.action-flip', function(){
               var attachmentPath = $(this).attr("data-image");
               $('.mainImage').addClass('mainImage-image-flip');
               $('div.actions').hide();
               $('div.actions-save').show();
               $('.action-apply').attr('data-action', '3');
            });
            
         	  $(document).on('click', '.action-cancel', function(){
               var attachmentPath = $(this).attr("data-image");
               $('.mainImage').removeClass('mainImage-image-grayscale').removeClass('mainImage-image-sepia').removeClass('mainImage-image-flip');
               $('div.actions').show();
               $('div.actions-save').hide();
               $('.action-apply').removeAttr('data-action');
            });
    
            $(document).on('change', "input[name='selectImage']", function(){
                var srcPath = $(this).attr("data-src");
                var srcType = $(this).attr("data-srctype");
                var srcFilename = $(this).attr("data-srcfilename")
    
                $('.action-bw').attr('data-image',srcFilename).attr('data-type',srcType);
                $('.action-sepia').attr('data-image',srcFilename).attr('data-type',srcType);
                $('.action-flip').attr('data-image',srcFilename).attr('data-type',srcType);
                $('.action-cancel').attr('data-image',srcFilename).attr('data-type',srcType);
                $('.action-apply').attr('data-image',srcFilename).attr('data-type',srcType);
                $('#mainImageSrc').attr("src", srcPath);
            });
    
            $(document).on('click', '.action-apply', function(){
               	var imageName = $(this).attr("data-image");
               	var imageType = $(this).attr("data-type");
               	var imageAction = $(this).attr("data-action");
               
               	jQuery.ajax({
                    url: "<?php echo $this->getUrl(); ?>wallpaper/index/imageCustomize?isAjax=true",
                    type: "POST",
                    data: {filename: imageName, fileType:imageType, fileAction:imageAction},
                    showLoader: true,
                    success: function (response) {
                      if(response.error == false)
                      {
                        $('.action-bw').attr('data-image',response.data.filename).attr('data-type',response.data.fileType);
                   			$('.action-sepia').attr('data-image',response.data.filename).attr('data-type',response.data.fileType);
                   			$('.action-flip').attr('data-image',response.data.filename).attr('data-type',response.data.fileType);
                   			$('.action-cancel').attr('data-image',response.data.filename).attr('data-type',response.data.fileType);
                   			$('.action-apply').attr('data-image',response.data.filename).attr('data-type',response.data.fileType);
    
             			      $('.mainImage').removeClass('mainImage-image-grayscale').removeClass('mainImage-image-sepia').removeClass('mainImage-image-flip');
        		           	$('div.actions').show();
        		           	$('div.actions-save').hide();
        	           		$('.action-apply').removeAttr('data-action');
    
                        $("#attachmentFiles").append(response.data.html);
                        $('#mainImageSrc').attr("src", response.data.path);
    
                        // Create dummy image to get real width and height
                        $("<img>").attr("src", response.data.path).load(function(){
                          var realWidth = this.width;
                          var realHeight = this.height;
                          var width = getSizeInCM(realWidth);
                          var height = getSizeInCM(realHeight);
                          /*alert("Original width=" + width + ", " + "Original height=" + height);*/
                        });
                      }
                      else
                      {
                        $('.mainImage').removeClass('mainImage-image-grayscale').removeClass('mainImage-image-sepia').removeClass('mainImage-image-flip');
                        $('div.actions').hide();
                        $('div.actions-save').show();
                        alert(response.message);
                      }
                    },
                   error: function (response) {
                        alert(response.message);
                   }
                });
            });
            
    
            /**** Upload Image ****/
            $('#uploadAttachment').click(function(e){e.preventDefault();  $('#attachment').trigger('click'); });
            
            $("#attachment").change(function(){
                var data = $("#frm_attachment").get(0);
                
                jQuery.ajax({
                 	url: "<?php echo $this->getUrl(); ?>wallpaper/index/addCustomize?isAjax=true' ?>",
                 	type: "POST",
                 	data: new FormData(data),
                 	processData: false,
                 	contentType: false,
                 	showLoader: true,
                 	success: function (response) {
                      if(response.error == false)
                      {
                   			$('.action-bw').attr('data-image',response.data.filename).attr('data-type',response.data.fileType);
                   			$('.action-sepia').attr('data-image',response.data.filename).attr('data-type',response.data.fileType);
                   			$('.action-flip').attr('data-image',response.data.filename).attr('data-type',response.data.fileType);
                   			$('.action-cancel').attr('data-image',response.data.filename).attr('data-type',response.data.fileType);
                   			$('.action-apply').attr('data-image',response.data.filename).attr('data-type',response.data.fileType);
    
                   			$('div.actions').show();
    
                      	$("#attachmentFiles").append(response.data.html);
                        $('#mainImageSrc').attr("src", response.data.path);
                      	$('#frm_attachment')[0].reset();
    
                      	// Create dummy image to get real width and height
                        $("<img>").attr("src", response.data.path).load(function(){
                          var realWidth = this.width;
                          var realHeight = this.height;
                          var width = getSizeInCM(realWidth);
                          var height = getSizeInCM(realHeight);
                          /*alert("Original width=" + width + ", " + "Original height=" + height);*/
                        });
                      }
                      else
                      {
                        alert(response.message);
                        $('#frm_attachment')[0].reset();
                      }
                 	},
                  error: function (response) {
                  	alert(response.message);
                  	$('#frm_attachment')[0].reset();
                  }
                });
            });
        });
    });
    </script>

    Step2: Create one “AddCustomize.php” file to upload an image.

    <?php
    namespace MagemonkeysWallpaperControllerIndex;
    
    use MagentoFrameworkJsonHelperData as JsonHelper;
    
    class AddCustomize extends MagentoFrameworkAppActionAction
    {
        protected $_pageFactory;
    	protected $connection;
        protected $_mediaDirectory;
        protected $_fileUploaderFactory;
        public $_storeManager;
    
    	public function __construct(
    		MagentoFrameworkAppActionContext $context,
            MagentoFrameworkAppResourceConnection $connection,
            JsonHelper $jsonHelper,
            MagentoFrameworkControllerResultJsonFactory $resultJsonFactory,
            MagentoFrameworkFilesystem $filesystem,
            MagentoMediaStorageModelFileUploaderFactory $fileUploaderFactory,
            MagentoStoreModelStoreManagerInterface $storeManager,
    		MagentoFrameworkViewResultPageFactory $pageFactory)
    	{
    		$this->_pageFactory = $pageFactory;
            $this->connection = $connection;      
            $this->jsonHelper = $jsonHelper;
            $this->resultJsonFactory = $resultJsonFactory;
            $this->_mediaDirectory = $filesystem->getDirectoryWrite(MagentoFrameworkAppFilesystemDirectoryList::MEDIA);
            $this->_fileUploaderFactory = $fileUploaderFactory;
            $this->_storeManager = $storeManager;
    		return parent::__construct($context);
    	}
    
    	public function execute(){
            
            $_postData = $this->getRequest()->getPost();
            
            $message = "";
            $newFileName = "";
            $error = false;
            $data = array();
            
            try{
                $target = $this->_mediaDirectory->getAbsolutePath('wallpaper/');        
                
                //attachment is the input file name posted from your form
                $uploader = $this->_fileUploaderFactory->create(['fileId' => 'attachment']);
                
                $_fileType = $uploader->getFileExtension();
                $uniqid = uniqid();
                $newFileName = $uniqid .'.'. $_fileType;
                
                /** Allowed extension types */
                $uploader->setAllowedExtensions(['jpg', 'jpeg', 'png']);
                /** rename file name if already exists */
                $uploader->setAllowRenameFiles(true);
                
                $result = $uploader->save($target, $newFileName); //Use this if you want to change your file name
                //$result = $uploader->save($target);
                if ($result['file']) {
                    
                    $_mediaUrl = $this->_storeManager->getStore()->getBaseUrl(MagentoFrameworkUrlInterface::URL_TYPE_MEDIA);
                    
                    $_src = $_mediaUrl.'wallpaper/'.$newFileName;
                    
                    $error = false;
                    $message = __("File has been successfully uploaded");
                    
                    $html = '<div class="image item base-image" data-role="image" id="'. $uniqid .'">
                                <div class="wallpaper-image-wrapper">
                                    <div class="radioContainer">
                                        <input data-src="'.$_src.'" data-srctype="'. $_fileType .'" data-srcfilename="'. $newFileName .'" checked="checked" class="selectImage selectImage-'. $uniqid .'" type="radio" name="selectImage" value="'. $uniqid .'" />
                                    </div>
                                    <div class="imageContainer">
                                        <img class="wallpaper-image" data-role="image-element" src="'.$_src.'" alt="">
                                    </div>
                                    <div class="delete-action">
                                        <button type="button" class="action-remove" data-role="delete-button" data-image="'.$newFileName.'" title="'. __('Delete image') .'"><span>'. __('Delete image') .'</span></button>
                                    </div>
                                </div>
                            </div>';
                    
                    $data = array('filename' => $newFileName, 'path' => $_mediaUrl.'wallpaper/'.$newFileName, 'fileType' => $_fileType, 'html' => $html);
                }
            } catch (Exception $e) {
                $error = true;
                $message = $e->getMessage();
            }
            
            $resultJson = $this->resultJsonFactory->create();
    
            return $resultJson->setData([
                        'message' => $message,
                        'data' => $data,
                        'error' => $error
            ]);
        }
    }
    

    Step3: Create one “DeleteCustomize.php” file to delete your uploaded image.

    <?php
    namespace MagemonkeysWallpaperControllerIndex;
    
    use MagentoFrameworkJsonHelperData as JsonHelper;
    
    class DeleteCustomize extends MagentoFrameworkAppActionAction
    {
        protected $_pageFactory;
    	protected $connection;
        protected $_mediaDirectory;
        protected $_fileUploaderFactory;
        public $_storeManager;
        protected $_file;
    
    	public function __construct(
    		MagentoFrameworkAppActionContext $context,
            MagentoFrameworkAppResourceConnection $connection,
            JsonHelper $jsonHelper,
            MagentoFrameworkControllerResultJsonFactory $resultJsonFactory,
            MagentoFrameworkFilesystem $filesystem,
            MagentoMediaStorageModelFileUploaderFactory $fileUploaderFactory,
            MagentoStoreModelStoreManagerInterface $storeManager,
            MagentoFrameworkFilesystemDriverFile $file,
    		MagentoFrameworkViewResultPageFactory $pageFactory)
    	{
    		$this->_pageFactory = $pageFactory;
            $this->connection = $connection;      
            $this->jsonHelper = $jsonHelper;
            $this->resultJsonFactory = $resultJsonFactory;
            $this->_mediaDirectory = $filesystem->getDirectoryWrite(MagentoFrameworkAppFilesystemDirectoryList::MEDIA);
            $this->_fileUploaderFactory = $fileUploaderFactory;
            $this->_storeManager = $storeManager;
            $this->_file = $file;
    		return parent::__construct($context);
    	}
    
    	public function execute(){
            
            $_postData = $this->getRequest()->getPost();
            
            $message = "";
            $newFileName = "";
            $success = false;
            
            $mediaRootDir = $this->_mediaDirectory->getAbsolutePath();
            $_fileName = $mediaRootDir .'wallpaper/'. $_postData['filename'];
            if ($this->_file->isExists($_fileName))  {
                try{
                    /*$this->attachment->load($_postData['imageID']);
                    $this->attachment->delete();*/
                    
                    $this->_file->deleteFile($_fileName);
                    $message = __('File removed successfully.');
                    $success = true;
                } catch (Exception $ex) {
                    $message = $ex->getMessage();
                    $success = false;
                }
            }else{
                $message = "File not found.";
                $success = false;
            }
            
            $resultJson = $this->resultJsonFactory->create();
    
            return $resultJson->setData([
                        'message' => $message,
                        'data' => '',
                        'success' => $success
            ]);
        }
    }
    

    Step4: Create one “ImageCustomize.php” file to give the effects to your uploaded image. I have given some effect to an image as per my requirements.

    <?php
    namespace MagemonkeysWallpaperControllerIndex;
    
    use MagentoFrameworkJsonHelperData as JsonHelper;
    
    class ImageCustomize extends MagentoFrameworkAppActionAction
    {
        protected $_pageFactory;
    	protected $connection;
        protected $_mediaDirectory;
        protected $_rootDirectory;
        protected $_fileUploaderFactory;
        public $_storeManager;
        protected $_file;
    
    	public function __construct(
    		MagentoFrameworkAppActionContext $context,
            MagentoFrameworkAppResourceConnection $connection,
            JsonHelper $jsonHelper,
            MagentoFrameworkControllerResultJsonFactory $resultJsonFactory,
            MagentoFrameworkFilesystem $filesystem,
            MagentoMediaStorageModelFileUploaderFactory $fileUploaderFactory,
            MagentoStoreModelStoreManagerInterface $storeManager,
            MagentoFrameworkFilesystemDriverFile $file,
    		MagentoFrameworkViewResultPageFactory $pageFactory)
    	{
    		$this->_pageFactory = $pageFactory;
            $this->connection = $connection;      
            $this->jsonHelper = $jsonHelper;
            $this->resultJsonFactory = $resultJsonFactory;
            $this->_mediaDirectory = $filesystem->getDirectoryWrite(MagentoFrameworkAppFilesystemDirectoryList::MEDIA);
            $this->_rootDirectory = $filesystem->getDirectoryRead(MagentoFrameworkAppFilesystemDirectoryList::ROOT);
            $this->_fileUploaderFactory = $fileUploaderFactory;
            $this->_storeManager = $storeManager;
            $this->_file = $file;
    		return parent::__construct($context);
    	}
    
    	public function execute(){
            
            $_postData = $this->getRequest()->getPost();
            
            $message = "";
            $newFileName = "";
            $error = false;
            $data = array();
            $uniqid = uniqid();
            $mediaRootDir = $this->_mediaDirectory->getAbsolutePath();
            $rootDirectory = $this->_rootDirectory->getAbsolutePath();
            $_fileType = $_postData['fileType'];
            $_fileAction = $_postData['fileAction'];
    
            if($_postData['filename'] == '10221276943_45e198c6c6_4k.jpg')
            {
                $newFileName = $uniqid .'.'.$_fileType;
                $filePath = $rootDirectory . $_postData['filename'];
                $_fileName = $mediaRootDir .'wallpaper/'. $newFileName;
                $newFullPathOfImage = $_fileName;
                copy($filePath, $_fileName);
            }
            else
            {
                $_fileName = $mediaRootDir .'wallpaper/'. $_postData['filename'];
                $newFullPathOfImage = $mediaRootDir .'wallpaper/'. $uniqid .'.'.$_fileType;
                $newFileName = $uniqid .'.'.$_fileType;
            }
    
            if ($this->_file->isExists($_fileName)){
                try{
                    if($_fileAction == 1) /*** Grayscale (Black & White) ***/
                    {
                        if(strtolower($_fileType) == 'jpg' || strtolower($_fileType) == 'jpeg')
                        {
                            $im = ImageCreateFromJpeg($_fileName); 
    
                            $imgw = imagesx($im);
                            $imgh = imagesy($im);
    
                            for ($i=0; $i<$imgw; $i++)
                            {
                                for ($j=0; $j<$imgh; $j++)
                                {
                                    // get the rgb value for current pixel
                                    $rgb = ImageColorAt($im, $i, $j); 
    
                                    // extract each value for r, g, b
                                    $rr = ($rgb >> 16) & 0xFF;
                                    $gg = ($rgb >> 8) & 0xFF;
                                    $bb = $rgb & 0xFF;
    
                                    // get the Value from the RGB value
                                    $g = round(($rr + $gg + $bb) / 3);
    
                                    // grayscale values have r=g=b=g
                                    $val = imagecolorallocate($im, $g, $g, $g);
    
                                    // set the gray value
                                    imagesetpixel ($im, $i, $j, $val);
                                }
                            }
    
                            imagejpeg($im, $newFullPathOfImage);
                            $message = __('Image converted to grayscale.');
                            imagedestroy($im);
                        }
                        else
                        {
                            $im = imagecreatefrompng($_fileName);
    
                            if($im && imagefilter($im, IMG_FILTER_GRAYSCALE))
                            {
                                $message = __('Image converted to grayscale.');
                                
                                imagepng($im, $newFullPathOfImage);
                                imagedestroy($im);
                            }
                            else
                            {
                                $message = __('Conversion to grayscale failed.');
                            }
                        }
                    }
                    else if($_fileAction == 2) /*** Sepia Color Scale ***/
                    {
                        if(strtolower($_fileType) == 'jpg' || strtolower($_fileType) == 'jpeg')
                        {
                            // Load
                            $im = ImageCreateFromJpeg($_fileName);
    
                            imagefilter($im, IMG_FILTER_GRAYSCALE);
                            imagefilter($im,IMG_FILTER_BRIGHTNESS,-10);
                            imagefilter($im, IMG_FILTER_COLORIZE, 65, 50, 0);
                            
                            // Output
                            imagejpeg($im, $newFullPathOfImage);
                            imagedestroy($im);
                        }
                        else
                        {
                            // Load
                            $im = imagecreatefrompng($_fileName);
    
                            imagefilter($im, IMG_FILTER_GRAYSCALE);
                            imagefilter($im,IMG_FILTER_BRIGHTNESS,-10);
                            imagefilter($im, IMG_FILTER_COLORIZE, 65, 50, 0);
                            
                            // Output
                            imagepng($im, $newFullPathOfImage);
                            imagedestroy($im);
                        }
    
                        $message = __('Image converted to sepia.');
                    }
                    else if($_fileAction == 3) /*** Flip Image ***/
                    {
                        if(strtolower($_fileType) == 'jpg' || strtolower($_fileType) == 'jpeg')
                        {
                            // Load
                            $im = ImageCreateFromJpeg($_fileName);
    
                            // Flip it horizontally
                            imageflip($im, IMG_FLIP_HORIZONTAL);
    
                            // Output
                            imagejpeg($im, $newFullPathOfImage);
                            imagedestroy($im);
                        }
                        else
                        {
                            // Load
                            $im = imagecreatefrompng($_fileName);
    
                            // Flip it horizontally
                            imageflip($im, IMG_FLIP_HORIZONTAL);
    
                            // Output
                            imagepng($im, $newFullPathOfImage);
                            imagedestroy($im);
                        }
    
                        $message = __('Image flipped.');
                    }
    
    
    
                    $_mediaUrl = $this->_storeManager->getStore()->getBaseUrl(MagentoFrameworkUrlInterface::URL_TYPE_MEDIA);
                    
                    $_src = $_mediaUrl.'wallpaper/'.$newFileName;
                    
                    $message = __("File has been successfully uploaded");
                    
                    $html = '<div class="image item base-image" data-role="image" id="'. $uniqid .'">
                                <div class="wallpaper-image-wrapper">
                                    <div class="radioContainer">
                                        <input data-src="'.$_src.'" data-srctype="'. $_fileType .'" data-srcfilename="'. $newFileName .'" checked="checked" class="selectImage selectImage-'. $uniqid .'" type="radio" name="selectImage" value="'. $uniqid .'" />
                                    </div>
                                    <div class="imageContainer">
                                        <img class="wallpaper-image" data-role="image-element" src="'.$_src.'" alt="">
                                    </div>
                                    <div class="delete-action">
                                        <button type="button" class="action-remove" data-role="delete-button" data-image="'.$newFileName.'" title="'. __('Delete image') .'"><span>'. __('Delete image') .'</span></button>
                                    </div>
                                </div>
                            </div>';
                    
                    $data = array('filename' => $newFileName, 'path' => $_mediaUrl.'wallpaper/'.$newFileName, 'fileType' => $_fileType, 'html' => $html);
                    $error = false;
                }
                catch (Exception $ex) {
                    $message = $ex->getMessage();
                    $error = true;
                }
            }else{
                $message = __("File not found.");
                $error = true;
            }
            
            $resultJson = $this->resultJsonFactory->create();
    
            return $resultJson->setData([
                'message' => $message,
                'data' => $data,
                'error' => $error
            ]);
        }
    }
    

     

    Magento 2: Assign your custom attribute in all attribute set programmatically.

    If you need to assign your custom attribute in all attribute set programmatically then you can used below steps:

    $objectManager = MagentoFrameworkAppObjectManager::getInstance();
     
    $attributeCode = 'is_featured';
    $attributeGroup = 'General';
     
    $eavSetup = $objectManager->create(MagentoEavSetupEavSetup::class);
    $config = $objectManager->get(MagentoCatalogModelConfig::class);
    $attributeManagement = $objectManager->get(MagentoEavApiAttributeManagementInterface::class);
     
    $entityTypeId = $eavSetup->getEntityTypeId(MagentoCatalogModelProduct::ENTITY);
    $attributeSetIds = $eavSetup->getAllAttributeSetIds($entityTypeId);
    foreach ($attributeSetIds as $attributeSetId) {
     if ($attributeSetId) {
     $group_id = $config->getAttributeGroupId($attributeSetId, $attributeGroup);
     if(empty($group_id)){ continue; }
     $attributeManagement->assign(
     'catalog_product',
     $attributeSetId,
     $group_id,
     $attributeCode,
     100
     );
     }
    }

    Here, we performed the task using objectManager. But You can perform it via module.

    How to add select all button in export products using plugin in Magento 2?

    If you want to implement “add select all button in Export Product” functionality in Magento 2, then please follow the below step.

    Step 1. Create Magemonkey/Exportproduct/registration.php file and add below code

    <?php
    MagentoFrameworkComponentComponentRegistrar::register(
        MagentoFrameworkComponentComponentRegistrar::MODULE,
        'Magemonkey_Exportproduct',
        __DIR__
    );

    Step 2. Create file of Magemonkey/Exportproduct/etc/module.xml

    <?xml version="1.0" ?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
        <module name="Magemonkey_Exportproduct" setup_version="1.0.0">
            <sequence>
                <module name="Magento_Backend"/>
            </sequence>
        </module>
    </config>

    Step 3. Create file of Magemonkey/Exportproduct/etc/adminhtml/di.xml

    <?xml version="1.0" ?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
        <type name="MagentoBackendBlockWidgetGridExtended">
            <plugin disabled="false" name="Magemonkey_Exportproduct_Plugin_Backend_Magento_Backend_Block_Widget_Grid_Extended" sortOrder="10" type="MagemonkeyExportproductPluginBackendMagentoBackendBlockWidgetGridExtended"/>
        </type>
    </config>
    

    Step 4. Create plugin file of Magemonkey/Exportproduct/Plugin/Backend/Magento/Backend/Block/Widget/Grid/Extended.php

    <?php
    namespace MagemonkeyExportproductPluginBackendMagentoBackendBlockWidgetGrid;
    class Extended
    {
        protected $request;
    
    	public function __construct(
            MagentoFrameworkAppRequestHttp $request
        ){
            $this->request = $request;
        }
        public function afterGetMainButtonsHtml(
            MagentoBackendBlockWidgetGridExtended $subject,
            $result
        ) {
        	$moduleName = $this->request->getModuleName();
            $controller = $this->request->getControllerName();
            $action     = $this->request->getActionName();
            $route      = $this->request->getRouteName();
    
            if($controller == 'export' && $action == 'getFilter'){ //check controller and action
            $result .= '<button id="" title="Select All" type="button" class="action-default scalable action-reset action-tertiary" onclick="export_filter_gridJsObject.selectAll()" data-action="grid-filter-reset" data-ui-id="widget-button-3"><span>Select All</span></button>';
        	}else{
        	$result .= '';
        	}
            return $result;
        }
    }
    

    Step 5. Override the /vendor/magento/module-import-export/view/adminhtml/templates/export/form/filter/after.phtml file and add below code after line 18

    export_filter_gridJsObject.selectAll = function () {
                // class admin__control-checkbox is selector 
                var inputs = document.getElementsByClassName("admin__control-checkbox");
                for(var i = 0; i < inputs.length; i++) {
                    if(inputs[i].type == "checkbox") {
                        inputs[i].checked = true;
                    }
                }
            };

     

    Note. Create the admin theme using this link and follow that step https://magemonkeys.com/magento-2-change-default-logo-of-admin-panel

    Magento 2: how to add new custom configuration option to editor global variable

    If you want to add new custom configuration option to editor global variable than you need to below steps:

    1. First you need to add your configuration option in your extension system.xml file.

    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
     <system>
     <section id="general">
     <group id="store_information">
     <field id="company_no" translate="label" type="text" sortOrder="65" showInDefault="1" showInWebsite="1" showInStore="1">
     <label>Company Number</label>
     </field>
     </group>
     </section>
     </system>
    </config>

    2. After add configuration option you need to register your configuration option in Magento Variables via your di.xml

    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
     <type name="MagentoVariableModelSourceVariables">
     <arguments>
     <argument name="configPaths" xsi:type="array"> 
     <item name="general/store_information" xsi:type="array">
     <item name="general/store_information/company_no" xsi:type="string">1</item>
     </item>
     </argument>
     </arguments>
     </type>
    </config>

    Add Hover image in a Product to display on listing page Magento 2

    1) Add “Hover” attribute

    Go to Stores > Attributes > Products and click on “Add New Attribute”

    Create the attribute “Hover” and Select “Media Image” in the “Catalog Input

    Type for Store Owner” dropdown and Save it.

    2) Now go to Attribute Set.

    Stores > Attributes > Attribute Set

    Add “hover” attribute to “Images” Group like the below screenshot.

    3) Now go to product and upload an image and select Hover like below screenshot.

    4) Now we have to use this attribute in the listing page. So we have to make ‘used_in_product_listing’ to 1.

    We can do that by using MySQL.
    You need to take “hover” Attribute_ID from admin.
    You can go to your “hover” attribute page in admin and get its ID from URL.
    Suppose that Attribute_ID is 99 in our case.
    Now, go to the database and select the “catalog_eav_attribute” table.
    Select the attribute with id 99 and change the value of the `used_in_product_listing` column to 1.
    Use below MySQL query :

    UPDATE catalog_eav_attribute SET used_in_product_listing = ‘1’ WHERE attribute_id = 99;

    5) Declare Hover attribute in view.xml
    view.xml should be in app/design/frontend/MyThemeVendor/MyTheme/etc/view.xml

    add below code

    <?xml version="1.0"?>
     <view xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Catalog:etc/view.xsd">
     <media>
      <images module="Magento_Catalog">
       <image id="hover_product_list" type="hover">
        <width>240</width>
        <height>300</height>
       </image>
      </images>
     </media>
    </view>

     

    6) Get “Hover” attribute in listing template

    Listing template is in app/design/frontend/MyThemeVendor/MyTheme/Magento_Catalog/templates/product/list.phtml

    User below helper to initialize hover image.

    <?php 
    $_imageHelper = $this->helper('MagentoCatalogHelperImage');
    $_imageHover = 'hover_product_list';
    ?>

    Search “product-image” class and use the below code and CSS to get a hover image.

    <div class="product-image">
        <div class="product-label">
            <?php 
                $newFromDate = $_product->getNewsFromDate();
                $newToDate = $_product->getNewsToDate(); 
                $now = date("Y-m-d H:m:s");
                // Get the Special Price
                $specialprice = $_product->getSpecialPrice(); 
                // Get the Special Price FROM date
                $specialPriceFromDate = $_product->getSpecialFromDate();
                // Get the Special Price TO date
                $specialPriceToDate = $_product->getSpecialToDate();
            ?>
            <?php if($specialprice && (($specialPriceFromDate <= $now && $specialPriceToDate >= $now) || (($specialPriceFromDate <= $now && $specialPriceFromDate != NULL) && $specialPriceToDate  == ''))): ?>
                <span class="sale"><?php echo __('Wras'); ?></span>
            <?php endif; ?>                        
            <?php if((($newFromDate <= $now && $newToDate >= $now) || (($newFromDate <= $now && $newFromDate != NULL) && $newToDate == NULL))): ?>
                <span class="new"><?php echo __('New'); ?></span>
            <?php endif; ?>
        </div>
        <div class="product-item-image" data-container="product-grid">
            <?php
                $productImage = $block->getImage($_product, $imageDisplayArea);
                if ($pos != null) {
                    $position = ' style="left:' . $productImage->getWidth() . 'px;'
                        . 'top:' . $productImage->getHeight() . 'px;"';
                }
            ?>
            <?php // Product Image ?>
            <a class="product-item-photo-focus" href="<?= $block->escapeUrl($_product->getProductUrl()) ?>">
                <?= $productImage->toHtml() ?>
            </a>
            <?php //Product Image Hovered ?>
            <?php
            $productImageHover = $_imageHelper->init($_product, $_imageHover);
            if ($pos != null) {
                $position = ' style="left:' . $productImage->getWidth() . 'px;'
            . 'top:' . $productImage->getHeight() . 'px;"';
            }
            ?>
            <?php if (strpos($productImageHover->getUrl(), 'Magento_Catalog/images/product/placeholder/hover.jpg') == false) { ?>
                <a href="<?php /* @escapeNotVerified */ echo $_product->getProductUrl() ?>" class="product-item-photo-hovered" tabindex="-1">
                    <img src="<?php echo $productImageHover->getUrl(); ?>" class="photo-image-hover" width="<?php echo $productImage->getWidth(); ?>" height="<?php echo $productImage->getWidth() ?>" alt="<?php echo $productImageHover->getLabel() ?>"/>
                </a>
            <?php } ?>
        </div>
    </div>

    CSS:

    .product-item-image {position: relative;}
    .product-item-image:hover .product-item-photo-hovered {opacity:1;z-index: 1;visibility: visible;}
    .product-item-photo-hovered {position: absolute;top: 0;left: 0;visibility: hidden;opacity: 0;transition: 0.6s;}

     

    Apply Free shipping Cart rule on subtotal after discount in Magento 2

    If you want to apply cart price rules like free shipping after discount and tax calculation, then you need to do customization in the sales rule module.

    To add new option in the cart price rule condition drop-down, You need to create custom extension like “Magemonkeys_Cartrule”.

    1. Create registration.php in app/code/Magemonkeys/Cartrule/

    <?php 
    MagentoFrameworkComponentComponentRegistrar::register(
        MagentoFrameworkComponentComponentRegistrar::MODULE,
        'Magemonkeys_Cartrule',
        __DIR__
    );

    2. Create module.xml in app/code/Magemonkeys/Cartrule/etc/

    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
        <module name="Magemonkeys_Cartrule" setup_version="1.0.0">
        </module>
    </config>

    3. Create di.xml in app/code/Magemonkeys/Cartrule/etc/adminhtml/di.xml

    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">    
        <preference for="MagentoSalesRuleModelRuleConditionAddress" type="MagemonkeysCartruleModelRuleConditionAddress" />
    </config>

    4. Create Address.php in app/code/Magemonkeys/Cartrule/Model/Rule/Condition/Address.php

    <?php
    
    namespace MagemonkeysCartruleModelRuleCondition;
    
    /**
     * Class Address
     */
    class Address extends MagentoSalesRuleModelRuleConditionAddress
    {
        
        /**
         * Load attribute options
         * @return $this
         */
        public function loadAttributeOptions()
        {
            $attributes = [
                'base_subtotal_with_discount' => __('Subtotal (Excl. Tax)'),
                'base_subtotal' => __('Subtotal'),
                'total_qty' => __('Total Items Quantity'),
                'weight' => __('Total Weight'),
                'shipping_method' => __('Shipping Method'),
                'postcode' => __('Shipping Postcode'),
                'region' => __('Shipping Region'),
                'region_id' => __('Shipping State/Province'),
                'country_id' => __('Shipping Country'),
            ];
    
            $this->setAttributeOption($attributes);
    
            return $this;
        }
    
        /**
         * Get input type
         * @return numeric
         */
        public function getInputType()
        {
            switch ($this->getAttribute()) {
                case 'base_subtotal_with_discount':
                case 'base_subtotal':
                case 'weight':
                case 'total_qty':
                    return 'numeric';
    
                case 'shipping_method':
                case 'payment_method':
                case 'country_id':
                case 'region_id':
                    return 'select';
            }
            return 'string';
        }
    
    }

    5. Run php bin/magento setup:upgrade command

    So you can see the “Subtotal (Excl. Tax)” option in cart price rule’s condition drop-down.

    Note: This option has already added by Magento in Magento 2.3.2+ version

    Magento 2 “Category” Filter Expand by default for all categories in layered navigation

    By default Magento collapse all filters in layered navigation. So if you want to expand only “Category” filter please follow below steps.

    First you have to override below PHTML file in your theme:

    vendor/magento/module-layered-navigation/view/frontend/templates/layer/view.phtml

    Like:

    app/design/frontend/[VENDOR_THEME_NAME]/[THEME_NAME]/Magento_LayeredNavigation/templates/layer/view.phtml

    After overriding above PHTML file find below code and replace with new code (Around line no. 33 to 42):

    <?php foreach ($block->getFilters() as $filter): ?>
        <?php if (!$wrapOptions): ?>
            <strong role="heading" aria-level="2" class="block-subtitle filter-subtitle"><?= /* @escapeNotVerified */ __('Shopping Options') ?></strong>
            <dl class="filter-options" id="narrow-by-list">
        <?php $wrapOptions = true; endif; ?>
            <?php if ($filter->getItemsCount()): ?>
                <dt role="heading" aria-level="3" class="filter-options-title"><?= $block->escapeHtml(__($filter->getName())) ?></dt>
                <dd class="filter-options-content"><?= /* @escapeNotVerified */ $block->getChildBlock('renderer')->render($filter) ?></dd>
            <?php endif; ?>
    <?php endforeach; ?>

    Replace with this code:

    <?php foreach ($block->getFilters() as $filter): ?>
        <?php if ($filter->getItemsCount()): ?>
            <?php if (!$wrapOptions): ?>
                <?php  
                    $collapsibleRange = '';
                    $cat = __('Category');
                    if($filter->getName() == $cat){
                	   $collapsibleRange = $catcount; 
                    }
                    $catcount++;
                ?>
                <strong role="heading" aria-level="2" class="block-subtitle filter-subtitle"><?php /* @escapeNotVerified */ echo __('Shopping Options') ?></strong>            
                <dl class="filter-options" id="narrow-by-list" data-role="content" data-mage-init='{"accordion":{"openedState": "active", "collapsible": true, "active": "<?php echo $collapsibleRange ?>", "multipleCollapsible": false}}'>
                <?php $wrapOptions = true; ?>
            <?php endif; ?>
            <div data-role="collapsible" class="filter-options-item">
                <div data-role="title" class="filter-options-title"><?php /* @escapeNotVerified */ echo __($filter->getName()) ?></div>
                <div data-role="content" class="filter-options-content"><?php /* @escapeNotVerified */ echo $block->getChildBlock('renderer')->render($filter); ?></div>
            </div>
        <?php endif; ?>
    <?php endforeach; ?>

    After doing all steps please clean the cache php bin/magento cache:clean and check in front-end categories page category filer is expand like below image:

    Magento 2.2.x Add file Attachment in email using custom module

    If you want to implement “add file attachment in the email” functionality in Magento 2, then please follow the below step.

    Step 1) Create Vendor/Module/etc/di.xml

    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
      <preference for="MagentoFrameworkMailTemplateTransportBuilder" type="VendorModuleModelMailTransportBuilder" />
    </config>

    Step 2) Please create the email template in Vendor/Module/view/frontend/email/email_template.html
    then after calling this file to Vendor/Module/etc/email_templates.xml

    Step 3) CreateTransportBuilder and extend with MagentoFrameworkMailTemplateTransportBuilder

    Create Vendor/Module/Model/Mail/TransportBuilder.php

    <?php
    namespace VendorModuleModelMail;
    
    use Zend_Mime;
    class TransportBuilder extends MagentoFrameworkMailTemplateTransportBuilder
    {
        public function addAttachment(
            $body,
            $mimeType    = Zend_Mime::TYPE_OCTETSTREAM,
            $disposition = Zend_Mime::DISPOSITION_ATTACHMENT,
            $encoding    = Zend_Mime::ENCODING_BASE64,
            $filename    = null
        ) {
            $this->message->createAttachment($body, $mimeType, $disposition, $encoding, $filename);
            return $this;
        }
    }
    

    Step 4) Send mail using controller in execute method
    Create Vendor/Module/Controller/Index/Index.php

    <?php
    namespace VendorModuleControllerIndex;
    
    use MagentoFrameworkAppActionContext;
    use MagentoFrameworkUrlFactory;
    use MagentoFrameworkAppFilesystemDirectoryList;
    use MagentoFrameworkTranslateInlineStateInterface;
    use VendorModuleModelMailTransportBuilder;
    use MagentoFrameworkAppConfigScopeConfigInterface;
    use MagentoStoreModelScopeInterface;
    use Zend_Mime;
    
    
    class Index extends MagentoCustomerControllerAbstractAccount {
        
        public function __construct(Context $context, 
            MagentoFrameworkFilesystem $fileSystem,
            StateInterface $inlineTranslation,
            TransportBuilder $transportBuilder,  
            ScopeConfigInterface $scopeConfig,
            UrlFactory $urlFactory, 
            MagentoFrameworkMessageManagerInterface $messageManager
        ) {
            $this->_filesystem = $fileSystem;
            $this->urlModel = $urlFactory->create ();
            $this->inlineTranslation = $inlineTranslation;
            $this->_transportBuilder = $transportBuilder;
            $this->scopeConfig = $scopeConfig;
            $this->messageManager = $messageManager;
            parent::__construct ( $context );
        }
        public function execute() {
            $objectManager = MagentoFrameworkAppObjectManager::getInstance();
            $storeurl = $objectManager->get( 'MagentoStoreModelStoreManagerInterface' )->getStore()->getBaseUrl();
            $result = array();
            $resultRedirect = $this->resultRedirectFactory->create ();
            if($_FILES['fileattach']['name']){
                try {
                    $uploader = $objectManager->create('MagentoMediaStorageModelFileUploader',['fileId' => 'fileattach']);
                    $uploader->setAllowedExtensions(['docx']);
                    $uploader->setAllowRenameFiles(true);
                    $uploader->setFilesDispersion(true);
                    // get media directory
                    $mediaDirectory = $this->_filesystem->getDirectoryRead(DirectoryList::MEDIA);
                    // save the image to media directory
                    
                    $result = $uploader->save($mediaDirectory->getAbsolutePath()."fileupload");
                    $email = $this->scopeConfig->getValue('trans_email/ident_general/email',ScopeInterface::SCOPE_STORE);
                    $name  = $this->scopeConfig->getValue('trans_email/ident_general/name',ScopeInterface::SCOPE_STORE);
                    $pdfFile = $result['path'].$result['file'];
                    $emailTemplateVariables['message'] = 'This is a test message.';
                    $this->inlineTranslation->suspend();
                    $this->_transportBuilder->setTemplateIdentifier('email_template') // Add your template name
                      ->setTemplateOptions(
                          [
                              'area' => MagentoFrameworkAppArea::AREA_FRONTEND,
                              'store' =>  $objectManager->get( 'MagentoStoreModelStoreManagerInterface' )->getStore()->getId(),
                          ]
                      )
                      ->setTemplateVars($emailTemplateVariables)
                      ->setFrom([
                          'name' => 'From Name',
                          'email' => "test1@gmail.com",
                      ])
                      ->addTo("test123@gmail.com", "To Name")
                      ->addAttachment(file_get_contents($pdfFile),$result['type'],Zend_Mime::DISPOSITION_ATTACHMENT,Zend_Mime::ENCODING_BASE64,$result['name']); //Attachment goes here.
                  try {
                      $transport = $this->_transportBuilder->getTransport();
                      $transport->sendMessage();
                      $this->inlineTranslation->resume();
                  } catch (Exception $e) {
                      echo $e->getMessage(); die;
                  }
                } catch (Exception $e) {
                    Zend_Debug::dump($e->getMessage());
                }
            }else{
                $url = $this->urlModel->getUrl ( '*/*/create', [ 
                        '_secure' => true 
                ] );
                $resultRedirect->setUrl ( $this->_redirect->error ( $url ) );
                $this->messageManager->addError(__('Please upload the document'));
                return $resultRedirect;
            }
          }
        }