Chapters Close

Symlinks in Magento 2

Jun 10th, 2019 4 min to read

In this post, I will be guiding you about symlink in Magento 2.

A symlink or a Symbolic Link is simply enough a shortcut to another file. It is a file that points to another file.

I have attached the below two images for identifying symlinks.

Symlinks are generated in the pub static folder of Magento 2 in developer mode.

Symlinks are generated in the pub static folder of Magento 2 in developer mode.

Common issue faced by Developer when working with knockout Js

In the development stage, when you are working with Js, knockout js and knockout template, the developer faces below issues

  • The changes in knockout js and knockout templates are not affecting on frontend when page load.
  • The developer has to delete the pub static folder or run static content deploy command every time when changes in js and knockout template file.

If you are facing this kind of issue in development, please verify the below steps.

  1. Is the developer mode enabled?
  2. Is symlink is generated in pub static folder or not?
  3. When doing development, open the inspect element in the browser and in the network tab and select the Disable cache checkbox.

1. Is the developer mode enabled?

  • Open the SSH Console and go to the root directory of Magento 2 and run the below command.
bin/magento deploy:mode:show
  • If it is not a developer mode then run below command to enable developer mode.
bin/magento deploy:mode:set developer

In development mode, symlinks are generated automatically when page load.

If you can’t see symlinks in pub static folder even after developer mode enabled. There might be the following reasons.

  • If you have run the static content deploy command in developer mode, it will generate copies instead of symlinks in pub static folder
  • If your web server is Apache then please make sure .htaccess file in pub/static directory otherwise symlinks will not generate.

Notes: When we run static content deploy command in developer mode, it generates copies instead of symlinks in pub static folder So we have to remove that file every time when doing development because symlinks are not created.

Originally, there is no need to run static content deploy command in developer mode. Because on page load it automatically creates symlinks.

Now if copies are generated in pub static folder, perform below steps to generate symlinks.

  • Remove pub static frontend and adminhtml folder(Don’t delete .htaccess file)
rm -rf pub/static/frontend/
rm -rf pub/static/adminhtml/
  • Now load the page, symlinks will create in pub static folder on-demand in developer mode.
  • Install below GitHub module, it will ensure the Magento setup:static-content: deploy will deploy with symlinks instead of copies in Developer mode.

WeareJH / m2-module-symlink-assets

FAQs

What are symlinks used for?


Symlinks are used to redirect to a different file or folder on your device. Symlink stands for symbolic link which is used in LINUX or UNIX. There are two types of symlinks. Soft links work like shortcuts to a file and directly point to it. Hard links direct you to the file storage.

Is symlink secure?


No, symlinks aren’t secure as they can be manipulated to expose data. Symlinks are prone to attacks that can steal data, change permissions, and corrupt files from unwarranted access. These breaches can be controlled by assigning “create symbolic links” only to trusted admins.

What are the advantages of using a symlink?


The advantages of using symlink are that they can link to both directories and across file systems. They are preferred over hard links as they create links at a namespace level. You can use symlinks to point to any files even if they differ in filesystem, permissions, configurations, and other parameters.

Can you symlink a directory?


Yes, you can symlink a directory. The process is similar to creating a symlink for a file. To create a symlink to a directory, choose a directory to create the link and select a link name. Then, run the command ln -s <target_directory> <link_name>

This article will help you to understand the dependency inversion principle in Magento 2.

Dependency inversion principle means that the high-level classes are not working directly with the low-level classes, they are using interfaces as an abstract layer.

In this case, the instantiation of new low-level objects inside the high-level classes (if needed) cannot be done utilizing the operator new. Instead, some of the Creational design patterns can be used, such as the Factory Method, Abstract Factory, Prototype.

This principle should not be implemented blindly for every class or module. If we have a class functionality that is more likely to remain consistent in the future there is no need to apply this principle.

By injecting the (low-level) dependencies, and using interfaces or abstract classes as types, you open up each class to a broader range of possibilities, since each type can be replaced by different implementations.

  • The Manager class doesn’t require any changes when adding SuperWorkers.
  • The risk to affect old functionality present in the Manager class is reduced as we don’t modify it.
  • No need to revise the unit testing for the Manager class.

Example:

Below is the code which supports the Dependency Inversion Principle.

In this new design, a new abstraction layer is added through the IWorker Interface.

// Dependency Inversion Principle - Good example
interface IWorker {
public void work();
}

class Worker implements IWorker{
public void work() {
   // ....working
}
}

class SuperWorker  implements IWorker{
public void work() {
   //.... working much more
}
}

class Manager {
IWorker worker;

public void setWorker(IWorker w) {
worker = w;
}

public void manage() {
worker.work();
  }
}

Now we will see an example of the Model class in Magento2 module Aureatelabs/InventoryLog.

app/code/Aureatelabs/InventoryLog/Model/Movement.php

namespace Aureatelabs\InventoryLog\Model;

use Aureatelabs\InventoryLog\Api\Data\MovementInterface;

class Movement extends \Magento\Framework\Model\AbstractModel implements MovementInterface
{

   /**
    * @return void
    */
   protected function _construct()
   {
       $this->_init('Aureatelabs\InventoryLog\Model\ResourceModel\Movement');
   }

   /**
    * Get movement_id
    * @return string
    */
   public function getMovementId()
   {
       return $this->getData(self::MOVEMENT_ID);
   }

   /**
    * Set movement_id
    * @param string $movementId
    * @return \Aureatelabs\InventoryLog\Api\Data\MovementInterface
    */
   public function setMovementId($movementId)
   {
       return $this->setData(self::MOVEMENT_ID, $movementId);
   }
…..

}

Now for the interface,

app/code/Aureatelabs/InventoryLog/Api/Data/MovementInterface.php

namespace Aureatelabs\InventoryLog\Api\Data;

interface MovementInterface
{
   const MOVEMENT_ID = 'movement_id';
   
   /**
    * Get movement_id
    * @return string|null
    */
   public function getMovementId();

   /**
    * Set movement_id
    * @param string $movementId
    * @return \Aureatelabs\InventoryLog\Api\Data\MovementInterface
    */
   public function setMovementId($movementId);

}

Grow your online business like 2,233 subscribers

    * This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.
    envelope

    Thank You!

    We are reviewing your submission, and will be in touch shortly.